/*
 *  CENodeRGBA.h
 *  LID Library
 *
 *  Created by Alexander Trutchenko on 09/11/11.
 *  Copyright 2011 League of Independent Developers. All rights reserved.
 *
 */

#ifndef __CE_NodeRGBA_h__
#define __CE_NodeRGBA_h__

#include "cocos2d.h"

namespace cocosext {

/////////////////////////////////////////////////////
//
/** CERGBAProtocolRecursive 
* CERGBAProtocolRecursive set color/opacity to all its children recursivly
*/
/////////////////////////////////////////////////////

class CERGBAProtocolRecursive 
{
public:
	CERGBAProtocolRecursive() {;}
	virtual ~CERGBAProtocolRecursive() {;}

public:
	void setColorRecursive(cocos2d::CCNode* node, const cocos2d::ccColor3B& color);
	void setOpacityRecursive(cocos2d::CCNode* node, GLubyte opacity);
	void setIsOpacityModifyRGBRecursive(cocos2d::CCNode* node, bool bValue);
};

/////////////////////////////////////////////////////
//
/** CENodeRGBA 
* CENodeRGBA set color/opacity to all its children recursivly
*/
/////////////////////////////////////////////////////

class CENodeRGBA : public cocos2d::CCNode, public cocos2d::CCRGBAProtocol, public CERGBAProtocolRecursive
{
protected:
// CCRGBAProtocol
	GLubyte _opacity;
	cocos2d::ccColor3B _color;
	bool _bOpacityModifyRGB;

protected:
	CENodeRGBA():_opacity(255), _color(cocos2d::ccWHITE), _bOpacityModifyRGB(true) {;}

public:
	static CENodeRGBA* node();

	virtual bool init() { return true; }

public:
// CCRGBAProtocol
    virtual void setColor(const cocos2d::ccColor3B& color);
	virtual const cocos2d::ccColor3B& getColor(void);
    virtual GLubyte getOpacity(void);
	virtual void setOpacity(GLubyte opacity);
	virtual void setIsOpacityModifyRGB(bool bValue);
	virtual bool getIsOpacityModifyRGB(void);
};

/////////////////////////////////////////////////////
//
/** CERecursiveRGBA 
* CERecursiveRGBA set color/opacity to all its children recursivly
* Used for nodes, which are NOT descendants of cocos2d::CCRGBAProtocol
*/
/////////////////////////////////////////////////////

template<typename T>
class CERecursiveRGBA : public T, public cocos2d::CCRGBAProtocol, public CERGBAProtocolRecursive
{
protected:
// CCRGBAProtocol
	GLubyte _opacity;
	cocos2d::ccColor3B _color;
	bool _bOpacityModifyRGB;

protected:
	CERecursiveRGBA():_opacity(255), _color(cocos2d::ccWHITE), _bOpacityModifyRGB(true) {;}

public:
	virtual ~CERecursiveRGBA() {;}

	static CERecursiveRGBA* node()
	{
		CERecursiveRGBA *pRet = new CERecursiveRGBA();
		CCAssert(pRet != NULL, NULL);
		if (pRet->init())
		{
			pRet->autorelease();
			return pRet;
		}
		else
		{
			CC_SAFE_DELETE(pRet)
			return NULL;
		}
	}

	virtual bool init() 
	{ 
		if (!T::init())
			return false;
		return true; 
	}

public:
// CCRGBAProtocol
	virtual void setColor(const cocos2d::ccColor3B& color)
	{
		_color = color;
		setColorRecursive(this, _color);
	}
	virtual const cocos2d::ccColor3B& getColor(void)	{ return _color; }
	virtual GLubyte getOpacity(void) { return _opacity;	}
	virtual void setOpacity(GLubyte opacity)
	{
		_opacity = opacity;
		setOpacityRecursive(this, _opacity);
	}
	virtual void setIsOpacityModifyRGB(bool bValue)
	{
		_bOpacityModifyRGB = bValue;
		setIsOpacityModifyRGBRecursive(this, bValue);
	}
	virtual bool getIsOpacityModifyRGB(void) {	return _bOpacityModifyRGB;	}
};

/////////////////////////////////////////////////////
//
/** CERecursiveRGBA_Ex 
* CERecursiveRGBA set color/opacity to all its children recursivly
* Used for nodes, which are descendants of cocos2d::CCRGBAProtocol
*/
/////////////////////////////////////////////////////

template<typename T>
class CERecursiveRGBA_Ex : public T, public CERGBAProtocolRecursive
{

protected:
	CERecursiveRGBA_Ex() {;}

public:
	virtual ~CERecursiveRGBA_Ex() {;}

	static CERecursiveRGBA_Ex* node()
	{
		CERecursiveRGBA_Ex *pRet = new CERecursiveRGBA_Ex();
		CCAssert(pRet != NULL, NULL);
		if (pRet->init())
		{
			pRet->autorelease();
			return pRet;
		}
		else
		{
			CC_SAFE_DELETE(pRet)
			return NULL;
		}
	}

	virtual bool init()
	{ 
		if (!T::init())
			return false;
		return true; 
	}

public:
// CCRGBAProtocol
	virtual void setColor(const cocos2d::ccColor3B& color)
	{
		T::setColor(color);
		setColorRecursive(this, color);
	}
	virtual void setOpacity(GLubyte opacity)
	{
		T::setOpacity(opacity);
		setOpacityRecursive(this, opacity);
	}
	virtual void setIsOpacityModifyRGB(bool bValue)
	{
		T::setIsOpacityModifyRGB(bValue);
		setIsOpacityModifyRGBRecursive(this, bValue);
	}
};

}; // end namespace cocosext

#endif // __CE_NodeRGBA_h__
